#include "widget.h"
#include "ui_widget.h"

//互斥量
pthread_mutex_t sendMutex;
pthread_mutex_t rcvMutex;

//发送信息
void *sendTerminalInfo(void *arg)
{
    //指向主窗口对象
    Widget *p = (Widget *)arg;
    while(1)
    {
        //若切换音乐再执行
        if(p->isChangeMusic == true)
        {
            //获取当前歌曲长度
            pthread_mutex_lock(&sendMutex);
            write(p->fifoFd,"get_time_length\n",strlen("get_time_length\n"));
            pthread_mutex_unlock(&sendMutex);
        }

        //若静音标志为真执行
        if(p->isMute == true)
        {
            //静音
            pthread_mutex_lock(&sendMutex);
            write(p->fifoFd, "mute 1\n", strlen("mute 1\n"));
            pthread_mutex_unlock(&sendMutex);
        }
        else
        {
            //解除静音
            pthread_mutex_lock(&sendMutex);
            write(p->fifoFd, "mute 0\n", strlen("mute 0\n"));
            pthread_mutex_unlock(&sendMutex);
        }

        //若快进标志为真执行
        if(p->isSeek == true)
        {
            //执行快进操作
            char buf[32]="";
            sprintf(buf,"seek %d\n",p->ui->progressSlider->sliderPosition()-p->currentTime);
            pthread_mutex_lock(&sendMutex);
            write(p->fifoFd,buf,strlen(buf));
            pthread_mutex_unlock(&sendMutex);
            p->isSeek=false;
        }

        //若音量改变标志为真执行
        if(p->isChangeVolume == true)
        {
            //修改音量操作
            char buf[64] = "";
            sprintf(buf,"volume %d 1\n",p->currentVolume);

            pthread_mutex_lock(&sendMutex);
            write(p->fifoFd,buf,strlen(buf));
            pthread_mutex_unlock(&sendMutex);
            //更新音量显示
            p->ui->volumeSlider->setValue(p->currentVolume);
            //修改音量标志
            p->isChangeVolume = false;
        }

        //持续发送当前时间
        pthread_mutex_lock(&sendMutex);
        write(p->fifoFd,"get_time_pos\n",strlen("get_time_pos\n"));
        pthread_mutex_unlock(&sendMutex);
        usleep(50*1000);
    }
    return 0;
}
//接送信息
void *rcvTerminalInfo(void *arg)
{
    //指向主窗口对象
    Widget *p = (Widget *)arg;
    while(1)
    {
        char buf[128]="";
        pthread_mutex_lock(&rcvMutex);
        int ret = read(p->fd[0],buf,sizeof(buf));
        pthread_mutex_unlock(&rcvMutex);

        //若读取的结果大于0执行
        if(ret > 0)
        {
            if(strncmp(buf,"ANS_TIME_POSITION",strlen("ANS_TIME_POSITION")) == 0)
            {
                //获取当前播放时间
                sscanf(buf,"ANS_TIME_POSITION=%d",&p->currentTime);
                sprintf(buf,"%02d:%02d",p->currentTime/60,p->currentTime%60);
                if(p->isUpdateProgress == true)
                {
                    //若开启了更新进度条则修改标签内的值
                    p->ui->progressSlider->setValue(p->currentTime);
                    p->ui->currentTimeLabel->setText(QString(buf));
                }
            }
            else if((strncmp(buf,"ANS_LENGTH",strlen("ANS_LENGTH")) == 0)&&(p->isChangeMusic == true))
            {
                //获取当前歌曲总长度
                sscanf(buf,"ANS_LENGTH=%d",&p->totalTime);
                sprintf(buf,"%02d:%02d",p->totalTime/60,p->totalTime%60);
                //更新标签内容
                p->ui->totalTimeLabel->setText(QString(buf));
                p->ui->progressSlider->setRange(0,p->totalTime);
                //关闭音乐修改标志
                p->isChangeMusic = false;
            }
        }
    }
    return 0;
}

//构造
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    //设置随机数种子
    srand(time(NULL));

    //初始化mplayer
    mplayerInit();

    //获取歌曲信息
    musicInfo = new LyricsList("");
    //歌曲列表
    playMap = new QMap<int,QString>;
    //喜欢列表
    likeList = new QList<QString>;

    //搜索音乐
    scanMusics();

    //样式初始化
    styleInit();

    //初始化互斥量
    pthread_mutex_init(&sendMutex,NULL);
    pthread_mutex_init(&rcvMutex,NULL);

    //创建发送线程
    pthread_t sendTid;
    pthread_create(&sendTid,NULL,sendTerminalInfo,this);
    pthread_detach(sendTid);

    //创建接收线程
    pthread_t rcvTid;
    pthread_create(&rcvTid,NULL,rcvTerminalInfo,this);
    pthread_detach(rcvTid);

    //设置初始化
    settingInit();

}

//析构
Widget::~Widget()
{
    //释放子进程
    kill(pid,9);

    //通过new新建的控件如果指定了父控件则不需要手动释放！！！！！！
    //释放歌词信息
    delete musicInfo;
    //释放播放列表
    delete playMap;
    //释放喜欢列表
    delete likeList;
    //释放ui
    delete ui;
}

//播放器初始化
void Widget::mplayerInit()
{
    //开启无名管道
    pipe(fd);
    //开启有名管道
    mkfifo("./fifo_cmd", 0666);
    //打开有名管道
    fifoFd = open("./fifo_cmd",O_RDWR);

    //创建子进程
    pid = fork();
    if(pid < 0)
        _exit(-1);
    else if(pid == 0)
    {
        //关闭子进程无名管道读端
        ::close(fd[0]);
        //重定向子进程文件描述符1到无名管道写端
        dup2(fd[1],1);

        execlp("mplayer", " mplayer ","-slave", "-quiet", "-idle","-input", "file=./fifo_cmd","./music", NULL);
    }
}

//样式初始化
void Widget::styleInit()
{
    //设置歌曲列表布局
    int musicListWidth = 180;
    int musicListHeight = 400;

    //新建歌曲列表
    musicListWidget = new QWidget(this);
    musicListWidget->setMinimumSize(musicListWidth, musicListHeight);
    musicListWidget->setMinimumHeight(musicListHeight);
    musicListWidget->setObjectName("musicListWidget");
    musicListWidget->setGeometry(0,0,musicListWidth,musicListHeight);
    musicListWidget->setStyleSheet("background-color: #35343a;");

    //设置歌曲列表
    ui->musicList->setParent(ui->musicTabWidget);
    ui->musicList->setMinimumSize(musicListWidth,musicListHeight-50);
    ui->musicList->setMinimumHeight(musicListHeight-50);
    ui->musicList->setObjectName("musicList");
    ui->musicList->setStyleSheet("QListWidget#musicList {color:white;font-size: 15px;}"
                                "QListWidget#musicList::item {background: #35343a;height:60;}"
                                "QListWidget#musicList::item:selected {color:#5edcf3;background: #545454;}"
                                "QListWidget#musicList::item:hover {background: #545454;color:#5edcf3;}");

    //设置我喜欢歌曲列表
    likeListWidget = new QListWidget(ui->musicTabWidget);
    likeListWidget->setMinimumSize(musicListWidth,musicListHeight-50);
    likeListWidget->setMinimumHeight(musicListHeight-50);
    likeListWidget->setObjectName("likeListWidget");
    likeListWidget->setStyleSheet("QListWidget#likeListWidget {color:white;font-size: 15px;}"
                                "QListWidget#likeListWidget::item {background: #35343a;height:60;}"
                                "QListWidget#likeListWidget::item:selected {color:#5edcf3;background: #545454;}"
                                "QListWidget#likeListWidget::item:hover {background: #545454;color:#5edcf3;}");

    //设置隐藏竖直滑动条
    likeListWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //设置隐藏水平滑动条
    likeListWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    //建立双击与槽函数的链接
    connect(likeListWidget,SIGNAL(itemDoubleClicked(QListWidgetItem*)),this,SLOT(on_likeListWidget_itemDoubleClicked(QListWidgetItem*)));


    //设置音乐侧边栏样式
    ui->musicTabWidget->setParent(musicListWidget);
    ui->musicTabWidget->clear();
    ui->musicTabWidget->setMinimumSize(musicListWidth,musicListHeight);
    ui->musicTabWidget->setMinimumHeight(musicListHeight);
    ui->musicTabWidget->setObjectName("musicTabWidget");
    ui->musicTabWidget->setGeometry(0,0,musicListWidth,musicListHeight);
    ui->musicTabWidget->insertTab(0,ui->musicList,tr("歌曲列表"));
    ui->musicTabWidget->insertTab(1,likeListWidget,tr("我喜欢"));
    ui->musicTabWidget->setStyleSheet("QTabWidget#musicTabWidget {background-color:rgb(245,245,245);border-radius: 10px;}"
                                     "QTabBar::tab {width:90px;height:40px;background-color:rgb(200,200,200);color:rgb(0,0,0);font:11pt '新宋体'}"
                                     "QTabBar::tab::selected {width:90px;height:40px;background-color:#c0c0c0;color:#9F5F9F;font:11pt '新宋体'}");

    //歌曲列表遮罩
    listMask = new QWidget(ui->musicTabWidget);
    listMask->setMinimumSize(ui->musicTabWidget->width(), 30);
    listMask->setMinimumHeight(30);
    listMask->setObjectName("listMask");
    listMask->setGeometry(0,ui->musicTabWidget->height()-25,ui->musicTabWidget->width(),30);
    listMask->setStyleSheet("border-image: url(:/images/mask.png);background-color: transparent;");


    //初始化歌词列表
    ui->titleLabel->adjustSize();
    ui->titleLabel->setStyleSheet("QLabel#titleLabel {color:white;font-size: 20px;}");


    ui->lyricsList->setStyleSheet("QListWidget#lyricsList {color:white;font-size: 15x;border:none;}"
                                  "QListWidget#lyricsList::item {background: transparent;height:30;}"
                                  "QListWidget#lyricsList::item:selected {color:#5edcf3;background: transparent;}"
                                  "QListWidget#lyricsList::item:hover {background: transparent;color:#70db93;border:none;}");


    //初始化按钮图标
    ui->previousBtn->setStyleSheet("QPushButton#previousBtn {border-image:url(:/images/btn_previous1.png)};}"
                                   "QPushButton#previousBtn:hover  {border-image:url(:/images/btn_previous2.png);}");

    ui->playBtn->setStyleSheet("QPushButton#playBtn  {border-image:url(:/images/btn_play1.png);}"
                               "QPushButton#playBtn:hover  {border-image:url(:/images/btn_play2.png);}"
                               "QPushButton#playBtn:checked {border-image:url(:/images/btn_pause1.png);}"
                               "QPushButton#playBtn:checked:hover {border-image:url(:/images/btn_pause2.png);}");

    ui->nextBtn->setStyleSheet("QPushButton#nextBtn  {border-image:url(:/images/btn_next1.png);}"
                               "QPushButton#nextBtn:hover  {border-image:url(:/images/btn_next2.png);}");

    //音量滑动条
    ui->volumeSlider->setRange(0,100);
    ui->volumeSlider->setStyleSheet("background-color: #35343a;border-radius: 8px;");


    ui->favoriteBtn->setStyleSheet("border-image:url(:/images/btn_favorite_no.png);");
    ui->modeBtn->setStyleSheet("border-image:url(:/images/btn_orde1.png);");
    ui->listBtn->setStyleSheet("border-image:url(:/images/btn_menu1.png);");
    ui->volumeBtn->setStyleSheet("border-image:url(:/images/btn_volume_open1.png);");


    isShow=false;
    // 左侧停靠
    musicListWidget->move(-musicListWidget->width(),0);
    //初始化动画
    anim = new QPropertyAnimation(musicListWidget,"geometry");
    anim->setEasingCurve(QEasingCurve::InOutSine);
    anim->setDuration(800);

    //隐藏音量框
    hideVolumeSlider();
}

//设置初始化
void Widget::settingInit()
{
    //设置当前播放索引
    currentPlayIndex=-1;
    //暂停标志
    isPlay=false;
    //音乐改变标志
    isChangeMusic=true;
    //歌词改变标志
    isChangeLyrices=false;
    //当前音乐名
    currentMusicName="";
    //是否快进
    isSeek=false;
    //是否为喜欢音乐
    isLike=false;
    //是否静音标志
    isMute=false;
    //播放模式
    playMode = LOOP;
    //歌曲总时间
    totalTime=0;
    //歌曲当前时间
    currentTime=0;

    //默认隐藏音量
    isVolumeShow=false;
    //当前音量
    currentVolume=50;
    //修改前音量
    previousVolume=currentVolume;
    //音量是否改变
    isChangeVolume=true;
    //进度条是否同步
    isUpdateProgress=true;
}

//搜索文件
void Widget::scanMusics()
{
    //当前文件的位置
    QDir dir(QCoreApplication::applicationDirPath() + "/music");
    QDir dirbsolutePath(dir.absolutePath());
    //如果目录存在
    if (dirbsolutePath.exists()) {
        //定义过滤器
        QStringList filter;
        //包含所有.mp3后缀的文件
        filter << "*.mp3";
        // 获取该目录下的所有文件
        QFileInfoList files = dirbsolutePath.entryInfoList(filter, QDir::Files);
        // 遍历
        int i = 0;
        for (i = 0; i < files.count(); i++)
        {
            //使用utf-8编码
            QString fileName = QString::fromUtf8(files.at(i).fileName().replace(".mp3", "").toUtf8().data());
            //插入播放列表
            ui->musicList->addItem(fileName);
            //插入map表
            playMap->insert(i,fileName);
        }
    }
}

//播放音乐
void Widget::playMusic(QString musicName)
{
    //是否切换音乐标志
    isChangeMusic = true;
    //播放/暂停标志
    isPlay = true;
    //音量改变标志
    isChangeVolume=true;
    //改变歌词标志
    isChangeLyrices=false;

    //切换歌曲
    char buf[128]="";
    sprintf(buf,"loadfile %s%s.mp3\n","./music/",musicName.toUtf8().data());
    write(fifoFd,buf,strlen(buf));
    pthread_mutex_unlock(&sendMutex);


    //设置歌词
    sprintf(buf,"./lyrics/%s.lrc",musicName.toUtf8().data());
    ui->lyricsList->clear();
    musicInfo->setMusicPath(buf);
    musicInfo->title=QString(musicName);

    //设置迭代器，用于遍历map数据
    QMap<int,QString>::const_iterator it = musicInfo->lyrics->constBegin();
    for(it = musicInfo->lyrics->constBegin();it != musicInfo->lyrics->constEnd();it++)
        ui->lyricsList->addItem(it.value());

    //更新播放信息(歌曲名、艺术家、专辑、当前歌曲名)
    ui->titleLabel->setText(musicInfo->title);
    ui->artistLabel->setText(musicInfo->artist);
    ui->albumLabel->setText(musicInfo->album);
    currentMusicName = musicName;

    //更新播放按钮状态
    ui->playBtn->setStyleSheet("border-image:url(:/images/btn_pause1.png);");
    //更新喜欢按钮状态
    if((isLike = likeList->contains(currentMusicName)) == true)
        ui->favoriteBtn->setStyleSheet("border-image:url(:/images/btn_favorite_yes.png);");
    else
        ui->favoriteBtn->setStyleSheet("border-image:url(:/images/btn_favorite_no.png);");
}

//显示音量条
void Widget::showVolumeSlider()
{
    //显示音量条并更新显示标志
    isVolumeShow = true;
    ui->volumeSlider->show();
}

//隐藏音量条
void Widget::hideVolumeSlider()
{
    //隐藏音量条并更新标志
    isVolumeShow = false;
    ui->volumeSlider->hide();
}

//开启静音
void Widget::volumeMute()
{
    //修改为静音图标
    ui->volumeBtn->setStyleSheet("border-image:url(:/images/btn_volume_close1.png);");
    //将修改前的音量赋值为当前音量
    previousVolume=currentVolume;
    //修改音量改变标志
    isChangeVolume=true;
    //修改静音标志
    isMute = true;
}

//解除静音
void Widget::volumeNotMute()
{
    //修改为打开静音图标
    ui->volumeBtn->setStyleSheet("border-image:url(:/images/btn_volume_open1.png);");
    //将当前音量赋值为修改前音量
    currentVolume=previousVolume;
    //修改音量标志
    isChangeVolume=true;
    //修改静音标志
    isMute = false;
}

//播放暂停
void Widget::on_playBtn_clicked()
{
    if (isPlay == true)
    {
        //若当前为播放状态则修改为暂停
        ui->playBtn->setStyleSheet("border-image:url(:/images/btn_play1.png);");
        pthread_mutex_lock(&sendMutex);
    }
    else
    {
        //若当前为暂停状态则修改为播放
        ui->playBtn->setStyleSheet("border-image:url(:/images/btn_pause1.png);");
        pthread_mutex_unlock(&sendMutex);
    }
    //发送暂停/播放指令
    write(fifoFd, "pause\n", strlen("pause\n"));
    isPlay = !isPlay;
}

//上一首
void Widget::on_previousBtn_clicked()
{
    //循坏模式
    //根据不同的模式设置不同的歌曲
    if(playMode == LOOP)
    {
        //顺序播放
        if(currentPlayIndex == 0)
            currentPlayIndex = playMap->keys().last();
        else
            currentPlayIndex--;
    }
    else if(playMode == RANDOM)
    {
        //随机播放
        currentPlayIndex = rand()%(playMap->keys().last()+1);
    }
    else if(playMode == SINGLE)
    {
        //单曲循环
        currentPlayIndex;
    }
    //更新歌曲信息
    playMusic(ui->musicList->item(currentPlayIndex)->text());
    ui->musicList->setCurrentRow(currentPlayIndex);
}

//下一首
void Widget::on_nextBtn_clicked()
{
    //循坏模式
    if(playMode == LOOP)
    {
        //顺序播放
        if(currentPlayIndex == playMap->keys().last())
            currentPlayIndex=0;
        else
            currentPlayIndex++;
    }
    else if(playMode == RANDOM)
    {
        //随机播放
        currentPlayIndex = rand()%(playMap->keys().last()+1);
    }
    else if(playMode == SINGLE)
    {
        //单曲循环
        currentPlayIndex;
    }
    //更新歌曲信息
    playMusic(ui->musicList->item(currentPlayIndex)->text());
    ui->musicList->setCurrentRow(currentPlayIndex);
}

//播放模式按钮
void Widget::on_modeBtn_clicked()
{
    //LOOP:随机播放
    //RANDOM:顺序播放
    //SINGLE:单曲循环
    if (playMode == LOOP)
    {
        //修改对应图标
        ui->modeBtn->setStyleSheet("border-image:url(:/images/btn_random1.png);");
        playMode = RANDOM;
    }
    else if(playMode == RANDOM)
    {
        //修改对应图标
        ui->modeBtn->setStyleSheet("border-image:url(:/images/btn_single1.png);");
        playMode = SINGLE;
    }
    else if(playMode == SINGLE)
    {
        //修改对应图标
        ui->modeBtn->setStyleSheet("border-image:url(:/images/btn_orde1.png);");
        playMode = LOOP;
    }
}

//喜欢按钮
void Widget::on_favoriteBtn_clicked()
{
    if (isLike == false)
    {
        //修改对应图标
        ui->favoriteBtn->setStyleSheet("border-image:url(:/images/btn_favorite_yes.png);");
        //若不是喜欢的歌曲则加入
        isLike = true;
        likeList->append(currentMusicName);
    }
    else if(isLike = true)
    {
        //修改对应图标
        ui->favoriteBtn->setStyleSheet("border-image:url(:/images/btn_favorite_no.png);");
        //若是喜欢的歌曲则删除
        isLike = false;
        likeList->removeOne(currentMusicName);
    }
}

//播放列表按钮
void Widget::on_listBtn_clicked()
{
    if(!isShow)
    {
        //设置动画起始位置
        anim->setStartValue(QRect(-this->rect().width(),0,musicListWidget->width(),musicListWidget->height()));
        //设置动画结束位置
        anim->setEndValue(QRect(0,0,musicListWidget->width(),musicListWidget->height()));
        //开始播放
        anim->start();

    }
    else
    {
        //设置动画起始位置
        anim->setStartValue(QRect(0,0,musicListWidget->width(),musicListWidget->height()));
        //设置动画结束位置
        anim->setEndValue(QRect(-this->rect().width(),0,musicListWidget->width(),musicListWidget->height()));
        //开始播放
        anim->start();
    }
    //修改动画显示状态
    isShow = !isShow;
}

//播放音量按钮
void Widget::on_volumeBtn_clicked()
{
    if(isVolumeShow==true)
    {
        //若为显示且未静音的状态则静音且关闭显示
        if(isMute == false)
            volumeMute();
        hideVolumeSlider();
    }
    else
    {
        //若未显示且为静音状态则解除静音状态
        if(isMute == true)
            volumeNotMute();
        else
            showVolumeSlider();
    }

}

//进度条滑块移动触发
void Widget::on_progressSlider_sliderMoved(int position)
{
    //修改进度条更新标志
    isUpdateProgress = false;
    //当前位置赋值为position
    currentPosition=position;
    char buf[16]="";
    sprintf(buf,"%02d:%02d",position/60,position%60);
    //更新信息
    ui->currentTimeLabel->setText(QString(buf));
}

//进度条滑块值改变时触发,显示歌词
void Widget::on_progressSlider_valueChanged(int value)
{
    int currentRow = currentRow = musicInfo->timeMap->key(value);

    if(currentRow != 0)
        isChangeLyrices = true;
    if(isChangeLyrices == false)
    {
        ui->lyricsList->setCurrentRow(0);
        ui->lyricsList->scrollToItem(ui->lyricsList->item(0),QAbstractItemView::PositionAtCenter);
    }
    if((isChangeLyrices == true)&&(currentRow != 0))
    {
        ui->lyricsList->setCurrentRow(currentRow);
        ui->lyricsList->scrollToItem(ui->lyricsList->item(currentRow),QAbstractItemView::PositionAtCenter);
    }

    //若进度条位置大于等于总时间且更新状态为真时触发下一首
    if((value+1 >= totalTime) && (isUpdateProgress=true))
    {
        emit on_nextBtn_clicked();
    }
}

//进度条释放滑块时触发
void Widget::on_progressSlider_sliderReleased()
{
    char buf[64] = "";
    sprintf(buf,"%02d:%02d",currentPosition/60,currentPosition%60);
    //更新进度条状态
    ui->progressSlider->setValue(currentPosition);
    ui->currentTimeLabel->setText(QString(buf));
    //若当前时间为总时间则触发下一首
    if(currentPosition+1 >= totalTime)
    {
        emit on_nextBtn_clicked();
        isUpdateProgress=true;
        return;
    }
    //更新快进标志
    isSeek=true;
    //更新进度条标志
    isUpdateProgress=true;
}

//双击播放
void Widget::on_musicList_itemDoubleClicked(QListWidgetItem *item)
{
    //调用播放
    playMusic(item->text());
}

//双击播放
void Widget::on_likeListWidget_itemDoubleClicked(QListWidgetItem *item)
{
    //调用播放
    playMusic(item->text());
}

//动画槽函数
void Widget::slotMoveWidget()
{
    //调用移动列表窗口
    ui->musicList->move(-ui->musicList->width(), 0);
}

//双击跳转歌词
void Widget::on_lyricsList_doubleClicked(const QModelIndex &index)
{
    //减少一秒可以用于减小误差
    int selectTime = musicInfo->timeMap->value(index.row())-1;
    ui->progressSlider->setValue(selectTime);
    //更新快进标志
    isSeek=true;
}

//双击获取播放列表的索引
void Widget::on_musicList_doubleClicked(const QModelIndex &index)
{
    //更新当前播放的索引
    currentPlayIndex = index.row();
}

//滑动音量条
void Widget::on_volumeSlider_sliderMoved(int position)
{
    if(position == 0)
    {
        //若滑动到0则设置恢复音量为50
        currentVolume=50;
        volumeMute();
    }
    //修改当前的音量为position
    currentVolume = position;
    //修改音量改变标志
    isChangeVolume=true;
}

//释放音量进度条时触发
void Widget::on_volumeSlider_sliderReleased()
{
    //隐藏音量框
    hideVolumeSlider();
}

//点击标签时触发
void Widget::on_musicTabWidget_tabBarClicked(int index)
{
    //更新歌曲列表
    likeListWidget->clear();
    //定义迭代器用于遍历list
    QList<QString>::const_iterator it = likeList->constBegin();
    for(;it != likeList->constEnd();it++)
    {
        likeListWidget->addItem(*it);
    }

}
